<?php

namespace App\Service;

use App\Constants\ErrorCode;
use App\Helpers\AliyunUtil;
use App\Helpers\DateUtil;
use App\Helpers\Helper;
use App\Helpers\ImUtil;
use App\Model\User;
use App\Model\UserDevice;
use App\Model\UserProfile;
use App\Model\WhitePhone;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Di\Annotation\Inject;
// use Hyperf\Logger\LoggerFactory;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\AsyncQueue\Driver\DriverInterface;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\Context;
use App\Helpers\AesUtil;

class BaseService
{
    /**
     * 请求对象
     * @Inject
     * @var RequestInterface
     */
    protected $request;

    /**
     * 响应对象
     * @Inject
     * @var ResponseInterface
     */
    protected $response;

    /**
     * 日志对象
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     * 消息队列
     * @var DriverInterface
     */
    protected $queueDriver;

    /**
     * 分页数量
     */
    protected $pageNum = 20;

    /**
     * 用户ID
     */
    protected $userId = 0;

    /**
     * 应用ID
     */
    protected $appId = 1;

    /**
     * 平台
     */
    protected $platform = 2;

    /**
     * 当前版本
     */
    protected $curVersion = '';

    /**
     * 当前版本
     */
    protected $curChannel = '';


    /**
     * 排除记录日志的路由
     */
    protected $logExludeRoute = [
        '/callback/rongcloud/msg',
        '/message/chat/users_info',
        '/moment/v1_1_8/new_msg',
        '/message/v1_1_8/quick_msg',
        '/index/user/detail',
        '/index/v1_1_4/user/detail_extra',
        '/message/v1_3_0/filter_msg'
    ];

    /**
     * 排除加密的接口
     * @var string[]
     */
    protected $excludeRouteData = [
        'act/reward/mylist',
        'act/reward/rank',
        'act/invite/info',
        'act/register/info',
        'guild/info',
        'auth/captcha/check_hv',
        'callback/baidu_ad',
        'callback/agora',
        'callback/rongcloud/msg',//融云消息回调
        'callback/rongcloud/checkmsg',//融云消息回调-消息检测
        'callback/rongcloud/online',//融云在线状态回调
        'callback/alipay',//支付宝回调
        'callback/wechat_pay',//微信支付回调
        'callback/sand_pay',//杉德支付回调
        'callback/apple_pay',//苹果内购回调
	'callback/new_pay',//新支付回调	
        'callback/dougong_pay',//斗拱支付回调
	'callback/yzh_order',//云账户下单回调
        'callback/gitee',//Gitee回调
        'callback/detection/checkmsg',//融云内容检测结果回调
        'callback/baidu_ad',
        'callback/baidu_extra_account',
        'web/user/freeze',
        'act/christmas',
        'web/violation/publicize',
        'callback/sm_video_call_callback',
        'callback/oppo_ad',
        'act/dragon/2023',
        'callback/share_link',
        //小程序回调获取openid
        'callback/get_dougong_openid',
    ];

    function __construct(DriverFactory $driverFactory)
    {
        // $this->queueDriver = $driverFactory->get('default');
    }

    /**
     * 通用响应方法
     * @return array|mixed
     */
    public function response()
    {
        //设置全局appid
        $this->appId = $this->request->input('appid', 1);
        //设置全局platform
        $this->platform = $this->request->input('platform', 2);
        //当前版本
        $this->curVersion = $this->request->input('version', '1.0.0');
        $this->curChannel = $this->request->input('channel', '');


	//return $this->request->path();

        Context::set('app_id', $this->appId);
        $locateCity = $this->request->input('locate_city', '');
        if(empty($locateCity)){
            $userInfo = UserProfile::getProfile($this->getUserId());
            $locateCity = empty($userInfo->locate_city) ? '' : $userInfo->locate_city;
        }
        Context::set('user_locate_city', $locateCity);

        //用户检测
        $user = $this->getUser();
        $checkResult = $this->checkUserLimit($user);
        if ($checkResult['errcode'] > 0) {
            return $this->setError($checkResult['errcode'], $checkResult['errmsg'], ['uid' => $user ? $user->id : 0]);
        }

        //用户ID
        $this->userId = $this->getUserId();

        //检测参数
        $reqs = $this->RoVerifyList();
        if (!empty($reqs)) {
            foreach ($reqs as $field => $req) {
                $rules = explode('|', $req);
                if ('required' == $rules[0] && $this->request->input($field) == '') {
                    return $this->setError(ErrorCode::PARAMETER_ERROR, "参数：{$field}为必传项！");
                }
            }
        }

        //更新参数信息
        $this->updateParams($user);

        //测试环境启用sql日志记录
        // check_dev_env() && Db::enableQueryLog();

        //调用业务
        $data = call_user_func([$this, 'handle'], $this->request);

        //记录日志
        $this->log();
        $uri = $this->request->path();
        if (isset($data['ret']) && $data['ret'] == -1) return $data;
        $ret = [
            'ret' => 0,
            'result' => 0,
	    'data' =>
	    env('DATA_AES_ON', true) == true && !in_array($uri,$this->excludeRouteData)
               ? AesUtil::encrypt(json_encode($data)) : $data,
          //  'data' =>   $data,
        ];
        if (check_dev_env()) $ret['user_id']  = $this->userId;
	
	if ($this->request->path() == 'callback/new_pay' && $data['result'] == 1) {
            $ret = 'success';
	} else if ($this->request->path() == 'callback/new_pay' && $data['result'] != 1) {
	    $ret = 'fail';
	} else if ($this->request->path() == 'callback/share_link') {
            $ret = $data;
	}



	return $ret;
    }

    /**
     * 检测用户状态
     */
    function checkUserLimit($user = null)
    {
        //设备被冻结
        $deviceId = $this->request->input('cid', '');
        if (!check_dev_env() && $deviceId && UserDevice::checkDeviceFreeze($deviceId)) {
            log_info(__CLASS__ . "==deviceError==cid:{$deviceId}");
            return ['errcode' => ErrorCode::DEVICE_NOT_VALID, 'errmsg' => '该设备异常，暂时无法使用！'];
        }
        if (!$user) return ['errcode' => 0];
        //用户状态
        if (in_array($user->status, [User::STATUS_FREEZE, User::STATUS_CANCELLATTED])) {
            return ['errcode' => ErrorCode::USER_NOT_VALID, 'errmsg' => '该账号异常，暂时无法使用！'];
        }
        //地理位置限制
        $locateCity = $this->request->input('locate_city', '');
        if ($locateCity && Helper::checkLocationRegLimited($locateCity)) {
            $profile = UserProfile::getProfile($user->id);
            //普通女用户，踢下线
            if ($profile &&  $profile->gender == 0 && UserProfile::checkRoleUser($profile->role)) {
                User::where('id', $user->id)->limit(1)->update(['status' => User::STATUS_FREEZE]);
                ImUtil::kickOut($user->id);
                UserDevice::freezeUserDevice($user->id);
                return ['errcode' => ErrorCode::LOGIN_TOKEN_EXP, 'errmsg' => '暂时限制使用～'];
            }
        }
        return ['errcode' => 0];
    }

    /**
     * 设置错误
     * @param $code
     */
    public function setError($code, $msg = '传入参数错误', $data = [])
    {
        $result = [
            'ret' => -1,
            'result' => intval($code),
            'res_info' => $msg,
        ];
        if (!empty($data)) {
            $uri = $this->request->path();
            $result['data'] = env('DATA_AES_ON', true) == true && !in_array($uri,$this->excludeRouteData)
                ? AesUtil::encrypt(json_encode($data)) : $data;

        }
        // else $result['data'] = $this->userId;
        return $result;
    }

    /**
     * 设置成功返回
     */
    public function setSuccess($msg = '', $data = [])
    {
        $result = [
            'ret' => 0,
            'result' => 0,
            'res_info' => $msg
        ];
        if (!empty($data)) $result['data'] = $data;
        // if (check_dev_env()) $result['user_id'] = $this->userId;
        return $result;
    }

    protected function getUser()
    {
        return $this->request->getAttribute('user');
    }

    protected function getUserId()
    {
        return $this->request->getAttribute('userId');
    }

    protected function getPage()
    {
        return $this->request->input('page', 1);
    }

    protected function RoVerifyList()
    {
        return [];
    }

    protected function log()
    {
        $path = $this->request->getPathInfo();
        $post = $this->request->all();
        if (in_array($path, $this->logExludeRoute)) return;
        // $userId = $this->getUserId();
        $post['client_ip'] = Helper::getClientIp();
        $logParam = !$post ? "" : "==" . json_encode($post);
        log_info("api=={$path}=={$this->userId}{$logParam}");
        // check_dev_env() && log_info("MysqlLog==" . json_encode(Db::getQueryLog()));
    }

    /**
     * 封装用户信息
     */
    protected function packBaseUserInfo($user = null)
    {
        $userProfile = $user->userProfile;
        if (!$userProfile) {
            return [
                'user_id' => $user->id,
                'user_name' => $user->user_name,
            ];
        }
        return [
            'user_id' => $user->id,
            'user_name' => $user->user_name,
            'phone' => $user->phone,
            'nick_name' => $userProfile->nick_name,
            'gender' => intval($userProfile->gender),
            'age' => DateUtil::newDateDiff($userProfile->birthday, date('Y-m-d'), 'Y'),
            'avatar' => AliyunUtil::IMG_HOST . $userProfile->avatar,
            'user_profile_id' => $userProfile->user_profile_id,
            //展示首页列表类型
            'show_list_type' => $userProfile->gender == 1 ? 'host' : 'user',
            //财富值
            'charm_value' => $userProfile->charm_value,
            'rich_value' => $userProfile->rich_value,
        ];
    }

    /**
     * 白名单手机号
     */
    function checkWhitePhone($phone = '')
    {
        $range = ['11811110001', '11811119999'];
        if ($phone <= $range[1] && $phone >= $range[0]) return true;
        $range = ['24000000001', '24000000901'];
        if ($phone <= $range[1] && $phone >= $range[0]) return true;
        // $valid = ['15020699598', '18032469315'];
        // $valid = explode(',', env('WHITE_PHONE', ''));
        if (in_array($phone, WhitePhone::getPhones())) return true;
        return false;
    }

    /**
     * 检测更新一些参数信息
     */
    protected function updateParams($user = null)
    {
        if (!$user) return false;
        $post = $this->request->all();
        $updateInfo = [];
        //更新用户信息
        if ($user->version < $post['version']) {
            $updateInfo['app_version'] = $post['version'];
        }
        if ($post['version'] && $user->version != $post['version']) {
            $updateInfo['version'] = $post['version'];
        }
        if (!$user->client_ip) $updateInfo['client_ip'] = Helper::getClientIp();
        if ($post['channel'] && !$user->channel) $updateInfo['channel'] = $post['channel'];
        if ($post['channel'] && $post['channel'] != $user->cur_channel) $updateInfo['cur_channel'] = $post['channel'];
        //地理位置
        if ((isset($post['latlong']) && $post['latlong']) ||
            (isset($post['locate_city']) && $post['locate_city'])
        ) {
            UserProfile::updateLocation($user->id, $post['latlong'], $post['locate_city']);
        }
        if (!empty($updateInfo)) {
            User::where('id', $user->id)->limit(1)->update($updateInfo);
            log_user_result($user->id, "UpdateParams:" . json_encode($updateInfo));
        }
    }
}
